using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace net.notdot.Attercop.Client
{
    public class TaskThreadCollection : ITaskThread
    {
        protected SortedList<string, TaskThread> tasks = new SortedList<string, TaskThread>();

        public EventHandler OnStarted;
        public EventHandler OnCompleted;
        public EventHandler<TaskCompletedEventArgs> OnTaskCompleted;

        public TaskThreadCollection()
        {
        }

        #region ITaskThread Members

        public void AddTask(ITask task)
        {
            string category = task.TaskCategory;

            lock (tasks)
            {
                if (!tasks.ContainsKey(category))
                {
                    if (OnStarted != null)
                        OnStarted(this, new EventArgs());

                    TaskThread ft = new TaskThread();
                    ft.OnCompleted += new EventHandler(ft_OnCompleted);
                    ft.OnTaskCompleted += new EventHandler<TaskCompletedEventArgs>(ft_TaskCompleted);
                    tasks.Add(category, ft);
                }

                tasks[category].AddTask(task);
                tasks[category].Start();
            }
        }

        private void ft_OnCompleted(object sender, EventArgs args)
        {
            lock (tasks)
            {
                tasks.RemoveAt(tasks.IndexOfValue((TaskThread)sender));
                if (tasks.Count == 0 && OnCompleted != null)
                    OnCompleted(this, new EventArgs());
            }
        }

        private void ft_TaskCompleted(object sender, TaskCompletedEventArgs args)
        {
            if (OnTaskCompleted != null)
                OnTaskCompleted(this, args);
        }

        public void Start()
        {
            foreach (TaskThread f in tasks.Values)
            {
                bool taskRunning = false;

                if (!f.IsRunning)
                {
                    f.Start();
                } else {
                    taskRunning = true;
                }

                if (!taskRunning && OnStarted != null)
                    OnStarted(this, new EventArgs());
            }
        }

        public void Stop()
        {
            foreach (TaskThread f in tasks.Values)
                f.Stop();
        }

        public TimeSpan EstimateTimeRemaining()
        {
            TimeSpan maxTime = TimeSpan.MinValue;

            foreach (TaskThread f in tasks.Values)
            {
                TimeSpan c = f.EstimateTimeRemaining();
                if (c.CompareTo(maxTime) > 0)
                    maxTime = c;
            }

            return maxTime;
        }

        public double TaskSize
        {
            get
            {
                double totalSize = 0;

                foreach (TaskThread f in tasks.Values)
                {
                    totalSize += f.TaskSize;
                }

                return totalSize;
            }
        }


        public bool IsRunning
        {
            get
            {
                foreach (TaskThread f in tasks.Values)
                    if (f.IsRunning)
                        return true;

                return false;
            }
        }

        public double TaskComplete
        {
            get {
                double totalComplete = 0;

                foreach (TaskThread f in tasks.Values)
                {
                    totalComplete += f.TaskComplete;
                }

                return totalComplete;
            }
        }

        #endregion
    }
}
